package com.cvte.sunkit.manage

import android.annotation.SuppressLint
import android.os.Environment
import android.util.Log
import com.cvte.sunkit.callback.RecordListener
import com.cvte.sunkit.model.PerfData
import com.cvte.sunkit.tools.*
import java.io.BufferedWriter
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStreamWriter
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.properties.Delegates

/**
 * 数据记录的管理类
 * 完成对数据文件的创建和数据的写入操作
 */
class RecordManager : RecordListener {
    private var mStartTime by Delegates.notNull<Long>()
    private var mEndTime by Delegates.notNull<Long>()

    private var mSysCpuUsage by Delegates.notNull<Double>()

    companion object {
        const val TAG = "RecordManage"
    }

    private var mPerfDataList = mutableListOf<PerfData>() // 性能数据

    /**
     * 读写文件操作，此方法在子线程调用
     */
    fun setPerfData(perfData: PerfData) { // 写入内存
        mPerfDataList.add(perfData)

        if (mPerfDataList.size > 10) {
            writeDataRecord() // 内存缓存了10个就写回磁盘、约等于间隔10秒写入一次
        }
    }

    override fun startRecord(startTime: Long) {
        this.mStartTime = startTime
        mPerfDataList.clear()
        Log.i(TAG, "startRecord所在线程: ${Thread.currentThread()}")

        writeDataRecord() // 开始录制，创建文件，写入时间
    }

    override fun stopRecord(endTime: Long) { // 结束录制
        this.mEndTime = endTime // 上传数据
        writeDataRecord() // 结束时要写回数据
        mPerfDataList.clear()
    }

    private fun writeDataRecord() {
        val file: File? = loadSaveDir()
        val charsetName = "GBK"
        val saveFile = File(file, "${shiftTimeFormat(mStartTime)}.csv")
        if (file?.canWrite() == true) {

            Log.i(TAG, "writeDataRecord: $saveFile")
            if (saveFile.createNewFile()) run {
                val writer =
                    BufferedWriter(OutputStreamWriter(FileOutputStream(saveFile), charsetName))
                writer.write("实时性能数据：开始时间:${shiftTimeFormat(mStartTime)}\n")
                writer.write("时间(s),总内存(mb),空闲内存(mb),cpu占用(%),当前帧率,延迟数,最长延时(ms),延迟占比(%),读取速率(mb/s),写回速率(mb/s)\n")
                writer.flush()
                writer.close()
            } else {

                Log.i(TAG, "writeDataRecord: 正在写入：${mPerfDataList.size}")
                val writer = BufferedWriter(
                    OutputStreamWriter(
                        FileOutputStream(saveFile, true),
                        charsetName
                    )
                )
                for (data in mPerfDataList) {
                    writer.append(
                        "${(data.currentTime - mStartTime) / 1000.0},${data.memTotal},${data.memAvail},${data.sysCpuUsage}," +
                                "${data.fpsDataWrapper.fps},${data.fpsDataWrapper.junkCount},${data.fpsDataWrapper.maxJunk}," +
                                "${data.fpsDataWrapper.junkPercent},${data.inSpeed},${data.outSpeed}\n"
                    )
                    writer.flush()
                }
                writer.close()
            }
            mPerfDataList.clear()
        }

    }

    //加载数据保存目录
    private fun loadSaveDir(): File? {
        val baseFile = File(Environment.getExternalStorageDirectory(), "sunkit")
        Log.i(TAG, "loadSaveDir: ${baseFile.absoluteFile}")
        if (!baseFile.exists()) {
            val result = baseFile.mkdirs()
            if (!result) {
                return null
            }
        }
        return baseFile
    }


    fun isNullPerfData(): Boolean {
        return mPerfDataList.isEmpty()
    }

    @SuppressLint("SimpleDateFormat")
    private fun shiftTimeFormat(currentTime: Long): String {
        val date = Date(currentTime)
        val pattern = "MM月dd日HH时mm分ss秒"
        val sdf = SimpleDateFormat(pattern)
        val formattedDateTime = sdf.format(date)
        return formattedDateTime.toString()
    }

    fun fetchData(): PerfData { // 在后台线程中执行数据获取操作
        val memList = MemoryTool.getTotalMemory()
        val memTotal = memList[0]
        val memAvail = memList[1]
        MemoryMonitor.updateMemoryCount(memAvail)

        mSysCpuUsage = CpuTool.getSysCpuUsage()
        CpuMonitor.updateCpuCount(mSysCpuUsage)

        val list = IOTool.getIOInAndOut()
        val inSpeed = list[0]
        val outSpeed = list[1]
        IOMonitor.updateCount(inSpeed, outSpeed)

        return PerfData(//记录数据
            System.currentTimeMillis(),
            memTotal,
            memAvail,
            mSysCpuUsage,
            inSpeed,
            outSpeed,
            FpsTool.getStartAndEndTime(),
            FpsToolPlus.getFps()
        )
    }
}